function init_function(f, str_prefix){
	var prefix_array = str_prefix.split("|");
	var elem = null;
	var fields;
	if(str_prefix.length > 0){
		for(var i=0; i<prefix_array.length; i++){
			fields = prefix_array[i].split(";");
				
			elem = new Object();
			elem.functionCode = Number(fields[0]);
			elem.chr = Number(fields[1]);
			elem.value = Number(fields[2]);
						
			f.prefix[f.prefixLen] = elem;
			f.prefixLen++;
		}
	}
}

function cal(f, vars, vals){
	var stack = {element:{}, top:-1};
	var ele = null;
	var operand1 = null;
	var operand2 = null;
	var res = 0;
	var i;
	var vIndex = -1;
	
	for(i=0; i<f.prefixLen; i++){
		
		switch(f.prefix[i].functionCode){
			case 0: //F_COE
			case 6: //F_CONSTANT
				ele = new Object();
				ele.value = f.prefix[i].value;
				stack.top++;
				stack.element[stack.top] = ele;
			break;
			
			case 1: //F_VAR
				if(vars.charCodeAt(0)==f.prefix[i].chr)
					vIndex = 0;
				else if(vars.charCodeAt(1)==f.prefix[i].chr)
					vIndex = 1;
				else if(vars.charCodeAt(2)==f.prefix[i].chr)
					vIndex = 2;
					
				if(vIndex >= 0){
					ele = new Object();
					ele.value = vals[vIndex];
					stack.top++;
					stack.element[stack.top] = ele;
				}
			break;
			
			case 3: //F_OPT
				operand1 = stack.element[stack.top];
				stack.element[stack.top] = null;
				stack.top--;
				operand2 = stack.element[stack.top];
				stack.element[stack.top] = null;
				stack.top--;
				
				switch(f.prefix[i].chr){
					case 0x2B: //43
						res = operand1.value + operand2.value;
						break;
						
					case 0x2D:
						//res = operand1.value - operand2.value;
						res = operand2.value - operand1.value;
						break; 
						
					case 0x2A:
						res = operand1.value * operand2.value;
						break;
						
					case 0x2F:
						if(operand2.value != 0)
							res = operand1.value / operand2.value;
						break; 
						
					case 0x5E: //POW is consider as an operator
						res = Math.pow(operand2.value, operand1.value);
						break;
				}
					
				
				//reuse operand1
				operand1.value = res;
				stack.top++;
				stack.element[stack.top] = operand1;
			break;
					
			case 2: //F_FUNCT
				operand1 = stack.element[stack.top];
				stack.element[stack.top] = null;
				stack.top--;
				
				switch(f.prefix[i].chr){
						
					//case 0x0B: //LOG(X,Y)
					//	operand2 = stack.element[stack.top];
					//	stack.element[stack.top] = null;
					//	stack.top--;
					//	res = Math.tan(operand1.value);
					//	break; 
					
						
					case 0x06: //SIN
						res = Math.sin(operand1.value);
						break; 
						
					case 0x07: //COS
						res = Math.cos(operand1.value);
						break;
						
					case 0x08: //TAN
						res = Math.tan(operand1.value);
						break; 
						
					case 0x12: //COTAN
						res = Math.costan(operand1.value);
						break;
						
					case 0x10: //SQRT
						res = Math.sqrt(operand1.value);
						break; 
						
					case 0x0A: //LN --> LOG JScript
						res = Math.log(operand1.value);
						break;
						
					case 0x14: //ACOS
						res = Math.acos(operand1.value);
						break;
				}
				
				//reuse operand1
				operand1.value = res;
				stack.top++;
				stack.element[stack.top] = operand1;
			break;
		}
	}
	return stack.element[stack.top].value;	
}

function world2Screen(coord, x, y){
	var xs = x * coord.scaleX + coord.X;
	var ys = coord.Y - (y * coord.scaleY);
	var result = [Math.round(xs),Math.round(ys)];
	return result;
}

function screen2World(coord, x, y){
	var result = new Array();
	result[0] = (x - coord.X)*1.0/coord.scaleX;
	result[1] = (coord.Y - y)*1.0/coord.scaleY;
	return result;
}
				
function drawCoordinator(coord, canvas){
	var context = canvas.getContext('2d');
	var drawY;
	var drawX;
	context.strokeStyle = '#0f0f0f';
	context.beginPath();
	context.moveTo(1, coord.Y);
	context.lineTo(599, coord.Y);
	context.moveTo(coord.X, 1);
	context.lineTo(coord.X, 299);
	if( (coord.X >= 0) && (coord.X <= 599) ){
		drawY = coord.Y + coord.scaleY;
		while(drawY < 300){
			context.moveTo(coord.X-5, drawY);
			context.lineTo(coord.X+5, drawY);
			drawY += coord.scaleY;
		}
		drawY = coord.Y - coord.scaleY;
		while(drawY > 0){
			context.moveTo(coord.X-5, drawY);
			context.lineTo(coord.X+5, drawY);
			drawY -= coord.scaleY;
		}
	}
	
	if( (coord.Y >= 0) && (coord.Y <= 299)){
		drawX = coord.X + coord.scaleX;
		while(drawX < 600){
			context.moveTo(drawX, coord.Y-5);
			context.lineTo(drawX, coord.Y+5);
			drawX += coord.scaleX;
		}
						
		drawX = coord.X - coord.scaleX;
		while(drawX > 0){
			context.moveTo(drawX, coord.Y-5);
			context.lineTo(drawX, coord.Y+5);
			drawX -= coord.scaleX;
		}
	}
	context.stroke();
}
function draw_f(coord, f, canvas, from, to, step){
	var x = [from];
	var y = cal(f,"x",x);
	var p1 = world2Screen(coord, x[0], y);
	var p2 = new Array();
	var context = canvas.getContext('2d');
	//alert(y + " " + p1[0] + " " + p1[1]);

	context.strokeStyle = '#ff0000';
	context.beginPath();
	context.moveTo(p1[0], p1[1]);
	while(x[0]<=to){
		x[0] = x[0] + step;
		y = cal(f,"x",x);
		p2 = world2Screen(coord, x[0], y);
		context.lineTo(p2[0], p2[1]);
	}
	context.stroke();
}
